package cn.unknowpupil.init.service.system.impl;

import cn.hutool.core.util.IdUtil;
import cn.unknowpupil.init.common.constant.SecurityConstants;
import cn.unknowpupil.init.domain.dto.LoginUser;
import cn.unknowpupil.init.domain.dto.SysUserDto;
import cn.unknowpupil.init.domain.system.SysUser;
import cn.unknowpupil.init.exceptions.HealthException;
import cn.unknowpupil.init.service.system.ICommonService;
import cn.unknowpupil.init.service.system.ISysUserService;
import cn.unknowpupil.init.mapper.system.SysUserMapper;
import cn.unknowpupil.init.utils.SecurityUtils;
import cn.unknowpupil.init.utils.StringUtils;
import cn.unknowpupil.init.utils.ValidateMobileUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Created at 2020-11-13 by  w10g <br>
 * Initialize SysUser  ... <br>
 * 用户信息表 核心业务处理实现类
 *
 * @author unknowpupil
 * @since 0.0.1
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {


    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;


    @Autowired
    private ICommonService commonService;
    /**
     * 新增
     *
     * @param sysUser {@link SysUser}  用户信息表
     * @return {@link SysUser}
     */
    @Override
    public boolean create(SysUser sysUser) {
        Long id = SecurityUtils.getLoginUser().getId();


        validUserParam(sysUser);
        if (StringUtils.isBlank(sysUser.getPassword())) {
            throw new HealthException("密码不能为空");
        }
        String encode = bCryptPasswordEncoder.encode(sysUser.getPassword());
        if (StringUtils.isBlank(encode)) {
            encode = bCryptPasswordEncoder.encode(sysUser.getPassword());
        }

        sysUser.setPId(id);


        sysUser.setPassword(encode);
        return save(sysUser);
    }

    /**
     * 详情
     *
     * @param id {@code Long}   SysUser ID
     * @return {@link SysUser}
     */
    @Override
    public SysUser info(Long id) {
        return getById(id);
    }

    /**
     * 删除
     *
     * @param ids {@code Long}   ids
     * @return {@link SysUser}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Long[] ids) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (!SecurityUtils.isSuperAdmin(loginUser.getPid())) {
            if(!SecurityUtils.isAdmin(loginUser.getPid())){
                throw new HealthException("无权限执行删除");
            }

        }

        List<Long> collect = Stream.of(ids).collect(Collectors.toList());
        collect.forEach(o -> {
            if (loginUser.getId().equals(o)) {
                throw new HealthException("删除项包含自己无法删除");
            }
//            boolean createSecret = isCreateSecret(o);
//            if(createSecret){
//                throw new HealthException("删除项有用户已经生成链接无法删除");
//            }
        });
        boolean b = removeByIds(collect);


        return b;
    }


    /**
     * 修改
     *
     * @param sysUser {@link SysUser}  用户信息表
     * @return {@link SysUser}
     */
    @Override
    public boolean update(SysUser sysUser) {
        return updateById(sysUser);
    }


    /**
     * 分页
     *
     * @param current {@code int} 页码
     * @param size    {@code int} 笔数
     * @param sysUser {@link SysUser}
     * @return {@code IPage<SysUser>}
     */
    @Override
    public IPage<SysUser> page(int current, int size, SysUser sysUser) {

        IPage<SysUser> page = new Page<>(current, size);
        return baseMapper.page(page, sysUser);
    }

    @Override
    public SysUser getUserByUsername(String username) {

        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getUserName, username);
        return getOne(wrapper);
    }

    @Override
    public boolean changeLimit(SysUser user) {
        return super.updateById(user);
    }
    @Override
    public boolean changePwd(SysUser user) {
        if (StringUtils.isBlank(user.getPassword())) {
            throw new HealthException("密码未必填项");
        }
        String encode = bCryptPasswordEncoder.encode(user.getPassword());
        user.setPassword(encode);
        return super.updateById(user);
    }

    @Override
    public boolean changeStatus(SysUser user) {
        return super.updateById(user);
    }


    @Override
    public String updateAvatar(MultipartFile file, Long userId) {
        String avatar = SecurityConstants.API_URL + commonService.uploadAvatar(file);
        SysUser byId = getById(userId);

        byId.setAvatar(avatar);
        boolean b = updateById(byId);
        if (b) {
            return avatar;
        } else {
            throw new HealthException("更新失败");
        }


    }




    @Override
    public String importUser(List<SysUserDto> userList, boolean updateSupport, LoginUser loginUser) {
        if (StringUtils.isNull(userList) || userList.size() == 0) {
            throw new HealthException("导入用户数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (SysUserDto user : userList) {
            try {
                // 验证是否存在这个用户
                SysUser u = getUserByUsername(user.getUserName());
                if (StringUtils.isNull(u)) {
                    u = new SysUser();
                    BeanUtils.copyProperties(user,u);
                    u.setPassword("123456");
                    u.setPId(loginUser.getId());
                    u.setCreateBy(loginUser.getUsername());
                    u.setDelFlag(0);
                    this.create(u);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、账号 " + user.getUserName() + " 导入成功");
                } else {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、账号 " + user.getUserName() + " 已存在");
                }
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、账号 " + user.getUserName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new HealthException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();

    }

    @Override
    public List<String> getAllSunUserByUserId(Long id) {
        return  baseMapper.getAllSunUserByUserId(id);

    }

    @Override
    public List<Long> getAllSunIdByUserId(Long id) {
        return  baseMapper.getAllSunIdByUserId(id);
    }





    @Override
    public boolean editProfile(SysUser user) {
        user.setUserName(null);
        validUserParam(user);

        return super.updateById(user);
    }

    /**
     * 校验用户参数
     *
     * @param sysUser {@link SysUser} 用户
     * @return
     */
    private boolean validUserParam(SysUser sysUser) {
         Assert.isTrue(StringUtils.isNotBlank(sysUser.getMobile()), "手机号手机号为空无法创建");
         boolean chinaPhoneLegal = ValidateMobileUtil.isChinaPhoneLegal(sysUser.getMobile());
         Assert.isTrue(chinaPhoneLegal, "手机号格式不对，请重试");

        boolean result = checkUserNameUnique(sysUser);
        Assert.isTrue(result, "用户名已经存在，请重试");
        result = checkEmailUnique(sysUser);
        Assert.isTrue(result, "邮箱已经存在，请重试");
        result = checkPhoneUnique(sysUser);
        Assert.isTrue(result, "手机号已经存在，请重试");

        return result;
    }

    /**
     * 校验用户名称是否唯一
     *
     * @param user {@link SysUser} 用户
     * @return 结果 true 是 false 不是
     */

    public boolean checkUserNameUnique(SysUser user) {
        int count = baseMapper.selectCount(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, user.getUserName()));
        if (count > 0) {
            return false;
        }
        return true;
    }

    /**
     * 校验手机号是否唯一
     *
     * @param user {@link SysUser} 用户
     * @return 结果 true 是 false 不是
     */

    public boolean checkPhoneUnique(SysUser user) {
        Long userId = StringUtils.isNull(user.getId()) ? -1L : user.getId();
        SysUser info = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getMobile, user.getMobile()));
        if (StringUtils.isNotNull(info) && info.getId().longValue() != userId.longValue()) {
            return false;
        }
        return true;
    }

    /**
     * 校验邮箱称是否唯一
     *
     * @param user {@link SysUser} 用户
     * @return 结果 true 是 false 不是
     */

    public boolean checkEmailUnique(SysUser user) {
        Long userId = StringUtils.isNull(user.getId()) ? -1L : user.getId();
        SysUser info = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getEmail, user.getEmail()));

        if (StringUtils.isNotNull(info) && info.getId().longValue() != userId.longValue()) {
            return false;
        }
        return true;
    }
}
